<template>
  <div>
    <el-input
      :value="value"
      readonly
      suffix-icon="el-icon-edit-outline"
      @click.native="handlerShowDialog"
    />
    <el-dialog
      :visible.sync="dialogVisible"
      title="编辑公式"
      width="800px"
      center
      :append-to-body="true"
      :show-close="true"
      :lock-scroll="true"
      :destroy-on-close="true"
      :close-on-click-modal="false"
      @open="show()"
    >
      <el-row :gutter="12">
        <el-col :span="24">
          <el-card
            shadow="never"
            :body-style="{ padding: '0' }"
            style="margin-bottom: 12px"
          >
            <div slot="header">
              <span>{{ label }}=</span>
            </div>
            <el-input
              ref="textarea"
              @blur="handleTextareaBlur"
              v-model="dialogValue"
              type="textarea"
              rows="6"
            />
          </el-card>
        </el-col>
        <el-col :span="7">
          <el-card shadow="never" :body-style="{ padding: '0' }">
            <div slot="header">
              <span>当前表单字段</span>
            </div>
            <div class="overBody">
              <div
                v-for="item in fieldList"
                :key="item.id"
                class="item"
                @dblclick="handlePushField(item.label)"
              >
                {{ item.label }}
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="7">
          <el-card shadow="never" :body-style="{ padding: '0' }">
            <div slot="header">
              <span>函数列表</span>
            </div>
            <div class="overBody">
              <div
                v-for="item in fnList"
                :key="item.name"
                class="item"
                @dblclick="handlePushFn(item.fn)"
                @mouseover="handleMouseoverFn(item)"
              >
                {{ item.name }}
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="10">
          <el-card shadow="never" :body-style="{ padding: '0' }">
            <div slot="header">
              <span>{{ curFn.name }}</span>
            </div>
            <div class="overBody">
              <div class="html" v-html="curFn.html" />
            </div>
          </el-card>
        </el-col>
      </el-row>

      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handlerSubmit">确 定</el-button>
        <el-button @click="handlerHideDialog">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import formTemplateJsonTransMixin from "../mixin/formTemplateJsonTransMixin";

export default {
  name: "FnText",
  mixins: [formTemplateJsonTransMixin],
  inject: ["getContext"],
  props: {
    value: {
      type: String,
      default: "",
    },
    label: {
      type: String,
      default: "",
    },
    defValue: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      dialogValue: "",
      dialogVisible: false,
      fieldList: [],
      fnList: [
        {
          name: "SUM",
          fn: "SUM()",
          html: `<div><p>SUM函数可以获取一组数值的总和</p><p>用法：SUM(数字1,数字2,...)</p><p>示例：SUM(物理成绩,化学成绩,生物成绩)返回三门课程的总分</p></div>`,
        },
        {
          name: "AVERAGE",
          fn: "AVERAGE()",
          html: `<div><p>AVERAGE函数可以获取一组数值的算术平均值</p><p>用法：AVERAGE(数字1,数字2,...)</p><p>示例：AVERAGE(物理成绩,化学成绩,生物成绩)返回三门课程的平均分</p></div>`,
        },
        {
          name: "ADD",
          fn: "ADD()",
          html: `<div><p>ADD函数用于返回组件值相加</p><p>用法：ADD(数字1,数字2,...)</p><p>示例：ADD(物理成绩,化学成绩,生物成绩)返回三门课程的总分数</p></div>`,
        },
        {
          name: "SUBTRACT",
          fn: "SUBTRACT()",
          html: `<div><p>SUBTRACT函数用于返回组件值相减</p><p>用法：SUBTRACT(数字1,数字2,...)</p><p>示例：SUBTRACT(物理成绩,化学成绩)返回两门课程的分差</p></div>`,
        },
        {
          name: "PRODUCT",
          fn: "PRODUCT()",
          html: `<div><p>PRODUCT函数可以获取一组数值的乘积</p><p>用法：PRODUCT(数字1,数字2,...)</p><p>示例：PRODUCT(单价,数量)获取总价,也就是单价和数量的乘积</p></div>`,
        },
        {
          name: "MOD",
          fn: "MOD()",
          html: `<div><p>MOD函数可以获取两数相除的余数</p><p>用法：MOD(被除数,除数)</p><p>示例：MOD(4,3)返回1,也就是4/3的余数</p></div>`,
        },
        {
          name: "DEALBIGMONEY",
          fn: "DEALBIGMONEY()",
          html: `<div><p>DEALBIGMONEY函数可以将金额转换为大写金额</p><p>用法：MOD(金额)</p><p>示例：DEALBIGMONEY(11.11)返回壹拾壹元壹角壹分</p></div>`,
        },
        {
          name: "ACCTTIMEDIFF",
          fn: "ACCTTIMEDIFF()",
          html: `<div><p>ACCTTIMEDIFF函数可以计算两个账务的时间差</p><p>用法：ACCTTIMEDIFF(开始时间,结束时间) 时间格式yyyy-MM-dd HH:mm:ss</p><p>示例：ACCTTIMEDIFF(2023-07-11 00:00:00,2023-07-17 00:00:00)返回6</p></div>`,
        },
      ],
      // 当前描述的函数
      curFn: {},
      // 光标点
      selectionPos: this.defValue.length,
    };
  },
  mounted() {
    this.$nextTick(() => {
      // this.dialogValue = this.defValue
    });
  },
  methods: {
    handlerShowDialog() {
      if (this.disabled) return;
      this.dialogVisible = true;
    },
    handlerSubmit() {
      this.dialogVisible = false;
      let fnArr = [];
      let $fn = this.dialogValue;
      this.fieldList.forEach((item) => {
        if (
          this.dialogValue.includes(`(${item.label})`) ||
          this.dialogValue.includes(`(${item.label},`) ||
          this.dialogValue.includes(`,${item.label},`) ||
          this.dialogValue.includes(`,${item.label})`)
        ) {
          fnArr.push(item.id);
          $fn = $fn.replaceAll(`(${item.label})`, `($[${item.id}]$)`);
          $fn = $fn.replaceAll(`(${item.label},`, `($[${item.id}]$,`);
          $fn = $fn.replaceAll(`,${item.label},`, `,$[${item.id}]$,`);
          $fn = $fn.replaceAll(`,${item.label})`, `,$[${item.id}]$)`);
        }
      });
      this.$emit("change", fnArr, $fn);
      this.$emit("input", this.dialogValue);
    },
    handlerHideDialog() {
      this.dialogVisible = false;
      this.dialogValue = this.defValue;
    },
    handlePushField(text) {
      this.dialogValue =
        this.dialogValue.substring(0, this.selectionPos) +
        text +
        this.dialogValue.substring(this.selectionPos, this.dialogValue.length);
      this.selectionPos = this.selectionPos + text.length;
      this.$nextTick(() => {
        this.setCaretToPos();
      });
    },
    handlePushFn(fn) {
      this.dialogValue =
        this.dialogValue.substring(0, this.selectionPos) +
        fn +
        this.dialogValue.substring(this.selectionPos, this.dialogValue.length);
      this.selectionPos = this.selectionPos + fn.length - 1;
      this.$nextTick(() => {
        this.setCaretToPos();
      });
    },
    handleMouseoverFn(item) {
      this.curFn = item;
    },
    handleTextareaBlur() {
      if (this.$refs.textarea.$refs.textarea.selectionStart) {
        this.selectionPos = this.$refs.textarea.$refs.textarea.selectionStart;
      }
    },
    show() {
      this.$nextTick(() => {
        this.dialogValue = this.defValue;
        this.fieldList = this.flattenFormJsonLabel({
          list: [...this.getContext.list],
        });
        this.curFn = this.fnList[0];
        //初始化光标
        this.setCaretToPos();
      });
    },
    // 控制光标位置
    setSelectionRange(input, selectionStart, selectionEnd) {
      if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);
      } else if (input.createTextRange) {
        const range = input.createTextRange();
        range.collapse(true);
        range.moveEnd("character", selectionEnd);
        range.moveStart("character", selectionStart);
        range.select();
      }
    },
    // 单光标
    setCaretToPos() {
      this.setSelectionRange(
        this.$refs.textarea.$refs.textarea,
        this.selectionPos,
        this.selectionPos
      );
    },
  },
};
</script>
<style lang="scss" scoped>
::v-deep .el-textarea__inner {
  border: 0;
  padding: 5px;
}
::v-deep .el-card__header {
  padding: 5px;
}
.overBody {
  height: 200px;
  width: 100%;
  overflow: auto;
}
.html {
  color: #666;
  padding: 5px;
}
.item {
  padding: 5px;
  color: #666;
  background: #fff;
  &:hover {
    background: #f7f7f7;
  }
}
</style>
